# Copyright (c) 2011 Sergey K.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.


from rs.status import OK, NO_CONTENT


__all__ = [
    'Response',
]


class Response(object):

    def __init__(self, status=None, reason=None, headers=None, entity=None):
        self.status  = status
        self.reason = reason
        self.headers = headers or {}
        self.entity = entity


def make_response(builder, entity=None, status=None, headers=None):
    builder.entity, builder.status, builder.headers = entity, status, headers
    if entity is None and status is None:
        builder.status = NO_CONTENT
    elif status is None:
        builder.status = OK


def make_error_response(error):
    def make_response(builder, entity=None, status=None, headers=None):
        builder.entity, builder.status, builder.headers = entity, status, headers
        if status is None:
            builder.status = error
    return make_response


class ResponseBuilder(object):

    def __init__(self, returned, make_response=make_response):
        assert make_response
        if returned is None:
            make_response(self)
        elif isinstance(returned, tuple):
            make_response(self, *returned)
        else:
            make_response(self, returned)
        self.tag = None
        self.cache = None

    def set_tag(self, tag):
        if tag:
            self.tag = tag

    def set_cache(self, cache):
        if cache:
            self.cache = cache

    def build(self, producer=None):
        from rs.message import set_entity, set_headers
        response = Response(self.status)
        entity = self.entity
        media = None
        if producer:
            media, produce = producer
            entity = produce(entity) if produce else entity
        set_entity(response, entity, media)
        set_headers(response, self.headers)
        if self.entity and self.tag:
            self.tag.set(response.headers, self.entity)
        if self.cache:
            self.cache.set(response.headers)
        return response